﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO.Ports;
using System.Management;
using System.Windows.Forms;
using Utils;

namespace 协议分析调试助手
{
    public partial class MainPage : Form
    {
        /// <summary>
        /// com口列表，用于保存实际的com名字
        /// </summary>
        string[] com_list;

        /// <summary>
        /// 智能串口
        /// </summary>
        SmartSerialPort[] smart_sp_list;

        /// <summary>
        /// 显示资源保护
        /// </summary>
        private readonly object disp_lock;

        /// <summary>
        /// 日志
        /// </summary>
        SmartLoger smartLoger;

        /// <summary>
        /// 颜色
        /// </summary>
        private readonly Color[] sp_color = new Color[2] { Color.DarkRed, Color.Blue };

        /// <summary>
        /// 声明添加文本委托函数模型
        /// </summary>
        /// <param name="color"></param>
        /// <param name="str"></param>
        private delegate void AppendString(Color color, String str);

        /// <summary>
        /// 信息框追加文本操作，用于提供给数据显示系统做委托函数
        /// color - 文本颜色
        /// str - 字符串
        /// </summary>
        /// <param name="color"></param>
        /// <param name="str"></param>
        private void txbInfo_AppendString(Color color, String str)
        {
            if (txbInfo.InvokeRequired == false)
            {
                txbInfo.Select(txbInfo.Text.Length, 0);
                txbInfo.Focus();
                txbInfo.SelectionColor = color;
                txbInfo.AppendText(str);
            }
            else
            {
                AppendString iv_fun = new AppendString(txbInfo_AppendString);
                txbInfo.BeginInvoke(iv_fun, color, str);
            }
        }

        /// <summary>
        /// 日志框追加文本操作，用于提供给日志系统做委托函数
        /// color - 文本颜色
        /// str - 字符串
        /// </summary>
        /// <param name="color"></param>
        /// <param name="str"></param>
        private void txbLog_AppendString(Color color, String str)
        {
            if (txbLog.InvokeRequired == false)
            {
                txbLog.Select(txbLog.Text.Length, 0);
                txbLog.Focus();
                txbLog.SelectionColor = color;
                txbLog.AppendText(str);
                txbLog.ScrollToCaret();
            }
            else
            {
                AppendString iv_fun = new AppendString(txbLog_AppendString);
                txbLog.BeginInvoke(iv_fun, color, str);
            }
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        public MainPage()
        {
            InitializeComponent();

            /* 禁止缩放 */
            MinimumSize = MaximumSize = Size;

            /* 显示锁 */
            disp_lock = new object();

            /* 创建日志系统 */
            smartLoger = new SmartLoger(LOG_LEVEL.LOG_DETAILS, txbLog_AppendString);

            /* 创建串口 */
            SerialPort[] sp_list = new SerialPort[2] { new SerialPort(), new SerialPort() };

            /* 创建智能串口 */
            smart_sp_list = new SmartSerialPort[2] { new SmartSerialPort(sp_list[0]), new SmartSerialPort(sp_list[1]) };
        }

        /// <summary>
        /// 获取所有COM端口
        /// </summary>
        private void GetSerialPorts()
        {
            /* 通过WMI获取COM端口 */
            string[] ss = SystemHardware.GetSerialPort();

            cmbPortName1.Items.Clear();
            cmbPortName2.Items.Clear();
            cmbPortName1.Text = "";
            cmbPortName2.Text = "";

            com_list = new string[ss.Length];
            string com, name;
            int start;
            int end;
            int index = 0;
            foreach (string str1 in ss)
            {
                smartLoger.LogDebug("搜索到 " + str1);
                start = str1.IndexOf("(") + 1;
                end = str1.IndexOf(")");

                com = str1.Substring(start, end - start);

                name = str1.Substring(0, start - 2);

                com_list[index++] = com;

                cmbPortName1.Items.Add("(" + com + ") " + name);
                cmbPortName2.Items.Add("(" + com + ") " + name);
            }
            if (ss.Length >= 2)
            {
                cmbPortName1.SelectedIndex = 0;
                cmbPortName2.SelectedIndex = 1;
            }
            else if (ss.Length == 1)
            {
                cmbPortName1.SelectedIndex = 0;
                cmbPortName2.SelectedIndex = 0;
            }
        }

        /// <summary>
        /// 窗口加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainPage_Load(object sender, EventArgs e)
        {
            cmbBaudRate.SelectedIndex = 0;

            /* 设置超时时间 */
            smart_sp_list[0].ReceiveTimeOut = Convert.ToInt32(cmbOverTime.Text);
            smart_sp_list[1].ReceiveTimeOut = Convert.ToInt32(cmbOverTime.Text);

            /* 获取端口 */
            GetSerialPorts();
        }

        /// <summary>
        /// 刷新串口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnFresh_Click(object sender, EventArgs e)
        {
            GetSerialPorts();
            cmbBaudRate.SelectedIndex = 0;
        }

        /// <summary>
        /// 连接串口1
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpen1_Click(object sender, EventArgs e)
        {
            try
            {
                if (smart_sp_list[0].serialPort.IsOpen)
                {
                    smart_sp_list[0].Stop();
                    cmbPortName1.Enabled = true;
                    if (smart_sp_list[0].serialPort.IsOpen == false)
                    {
                        cmbBaudRate.Enabled = true;
                        btnFresh.Enabled = true;
                    }
                    btnOpen1.Text = "打开";
                    smartLoger.LogDebug("串口" + smart_sp_list[0].serialPort.PortName + "关闭成功");
                }
                else
                {
                    smart_sp_list[0].serialPort.PortName = com_list[cmbPortName1.SelectedIndex].ToString();
                    smart_sp_list[0].serialPort.BaudRate = Convert.ToInt32(cmbBaudRate.Text);
                    smart_sp_list[0].ReceiveFinishedEvent += new SmartSerialPort.ReceiveFinishedEventHandler(SerialPort1_ReceiveFinishedEventHandler);
                    smart_sp_list[0].Start();

                    cmbPortName1.Enabled = false;
                    cmbBaudRate.Enabled = false;
                    btnFresh.Enabled = false;
                    btnOpen1.Text = "关闭";
                    smartLoger.LogDebug("串口" + smart_sp_list[0].serialPort.PortName + "打开成功");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("操作失败\r\n" + ex.Message);
            }
        }

        /// <summary>
        /// 连接串口2
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpen2_Click(object sender, EventArgs e)
        {
            try
            {
                if (smart_sp_list[1].serialPort.IsOpen)
                {
                    smart_sp_list[1].Stop();
                    cmbPortName2.Enabled = true;
                    if (smart_sp_list[0].serialPort.IsOpen == false)
                    {
                        cmbBaudRate.Enabled = true;
                        btnFresh.Enabled = true;
                    }
                    btnOpen2.Text = "打开";
                    smartLoger.LogDebug("串口" + smart_sp_list[1].serialPort.PortName + "关闭成功");
                }
                else
                {
                    smart_sp_list[1].serialPort.PortName = com_list[cmbPortName2.SelectedIndex].ToString();
                    smart_sp_list[1].serialPort.BaudRate = Convert.ToInt32(cmbBaudRate.Text);
                    smart_sp_list[1].ReceiveFinishedEvent += new SmartSerialPort.ReceiveFinishedEventHandler(SerialPort2_ReceiveFinishedEventHandler);
                    smart_sp_list[1].Start();

                    cmbPortName2.Enabled = false;
                    cmbBaudRate.Enabled = false;
                    btnFresh.Enabled = false;
                    btnOpen2.Text = "关闭";
                    smartLoger.LogDebug("串口" + smart_sp_list[1].serialPort.PortName + "打开成功");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("操作失败\r\n" + ex.Message);
            }
        }

        /// <summary>
        /// 修改超时时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbOverTime_ValueChanged(object sender, EventArgs e)
        {
            int time_out = (int)cmbOverTime.Value;
            /* 设置超时时间 */
            smart_sp_list[0].ReceiveTimeOut = time_out;
            smart_sp_list[1].ReceiveTimeOut = time_out;

            smartLoger.LogDebug("超时时间：" + time_out + "ms");
        }

        /// <summary>
        /// 清除显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClear_Click(object sender, EventArgs e)
        {
            txbInfo.Clear();
        }

        /// <summary>
        /// 字体设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnFontSetup_Click(object sender, EventArgs e)
        {
            FontDialog dialog = new FontDialog();
            dialog.Font = txbInfo.Font;
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                txbInfo.Font = dialog.Font;
            }
        }

        /// <summary>
        /// 主窗口关闭事件处理，应为存在多线程，需要关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainPage_FormClosing(object sender, FormClosingEventArgs e)
        {
            System.Environment.Exit(0);
        }

        /// <summary>
        /// 串口1接收完成处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="frame"></param>
        void SerialPort1_ReceiveFinishedEventHandler(object sender, SmartSerialPortReceiveFrame frame)
        {
            lock (disp_lock)
            {
                smartLoger.LogDetails("sp1 rx ok");
                txbInfo_AppendString(sp_color[0], frame.TimeString + " " + smart_sp_list[0].serialPort.PortName + "\r\n");
                txbInfo_AppendString(sp_color[0], frame.HexString + "\r\n");
            }
        }

        /// <summary>
        /// 串口2接收完成处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="frame"></param>
        void SerialPort2_ReceiveFinishedEventHandler(object sender, SmartSerialPortReceiveFrame frame)
        {
            lock (disp_lock)
            {
                smartLoger.LogDetails("sp2 rx ok");
                txbInfo_AppendString(sp_color[1], frame.TimeString + " " + smart_sp_list[1].serialPort.PortName + "\r\n");
                txbInfo_AppendString(sp_color[1], frame.HexString + "\r\n");
            }
        }
    }
}
